import { RuntimeError } from '@ibiz-template/core';
import {
  ViewEngineBase,
  ViewController,
  IEditFormController,
  SysUIActionTag,
  EventBase,
  IEditViewState,
  IEditViewEvent,
  ControlVO,
  calcDeCodeNameById,
  OpenAppViewCommand,
  IModalData,
  getAppViewRef,
} from '@ibiz-template/runtime';
import { IAppDEEditView } from '@ibiz/model-core';

export class EditViewEngine extends ViewEngineBase {
  /**
   * 视图控制器
   *
   * @protected
   * @type {ViewController<
   *     IAppDEEditView,
   *     IEditViewState,
   *     IEditViewEvent
   *   >}
   * @memberof EditViewEngine
   */
  protected declare view: ViewController<
    IAppDEEditView,
    IEditViewState,
    IEditViewEvent
  >;

  get form(): IEditFormController {
    return this.view.getController('form') as IEditFormController;
  }

  async onCreated(): Promise<void> {
    await super.onCreated();
    const { childNames, modal } = this.view;
    childNames.push('form');

    modal.hooks.shouldDismiss.tapPromise(async context => {
      if (this.form.state.modified) {
        const isAllow = await ibiz.modal.confirm({
          title: '关闭提醒',
          desc: '表单数据已经修改，确定要关闭？',
        });
        if (!isAllow) {
          context.allowClose = false;
          // return null;
        }
      }
    });
  }

  async onMounted(): Promise<void> {
    await super.onMounted();
    const { model, evt } = this.view;

    // 监控form事件
    const formDeId = this.form.model.appDataEntityId;
    const formDataStateChange = (event: EventBase): void => {
      const data = event.data[0];
      this.toolbar?.calcButtonState(data, formDeId);
      if (data.srfkey) {
        evt.emit('onViewInfoChange', { dataInfo: data.srfmajortext || '' });
      } else {
        evt.emit('onViewInfoChange', { dataInfo: '新建' });
      }
    };

    this.form.evt.on('onLoadSuccess', event => {
      formDataStateChange(event);
      evt.emit('onDataChange', { ...event, actionType: 'LOAD' });
    });
    this.form.evt.on('onLoadDraftSuccess', event => {
      formDataStateChange(event);
      evt.emit('onDataChange', { ...event, actionType: 'LOADDRAFT' });
    });
    this.form.evt.on('onSaveSuccess', event => {
      const deName = calcDeCodeNameById(this.view.model.appDataEntityId!);
      const formData = event.data[0];
      if (this.view.context[deName] !== formData.srfkey) {
        this.view.context[deName] = formData.srfkey;
      }
      formDataStateChange(event);
      evt.emit('onDataChange', { ...event, actionType: 'SAVE' });
    });
    this.form.evt.on('onRemoveSuccess', event => {
      formDataStateChange(event);
      evt.emit('onDataChange', { ...event, actionType: 'REMOVE' });
    });

    if (!this.view.state.noLoadDefault && model.loadDefault) {
      this.load();
    }
  }

  getData(): IData[] {
    return this.form.getData();
  }

  async load(): Promise<IData> {
    return this.form.load();
  }

  async save(): Promise<IData> {
    return this.form.save();
  }

  async refresh(): Promise<void> {
    await this.load();
    // this.view.evt.emit('refreshed', [data]);
  }

  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
  async call(key: string, args: any): Promise<IData | null | undefined> {
    if (key === SysUIActionTag.SAVE) {
      await this.form.save();
      return null;
    }
    if (key === SysUIActionTag.SAVE_AND_EXIT) {
      await this.form.save();
      return { closeView: true };
    }
    if (key === SysUIActionTag.REMOVE_AND_EXIT) {
      const res = await this.form.remove();
      return { closeView: res };
    }
    if (key === SysUIActionTag.SAVE_AND_NEW) {
      this.saveAndNew();
    }
    if (key === SysUIActionTag.REFRESH) {
      await this.refresh();
    }
    if (key === SysUIActionTag.SAVE_AND_START) {
      await this.wfStart();
    }
    if (key === SysUIActionTag.VIEW_WF_STEP) {
      await this.wfSubmit();
    }
    return super.call(key, args);
  }

  /**
   * 保存并新建
   *
   * @author zk
   * @date 2023-06-01 01:06:59
   * @return {*}
   * @memberof EditViewEngine
   */
  async saveAndNew(): Promise<void> {
    await this.form.save();
    this.form.state.data = new ControlVO();
    // 置空主键
    this.view.context[calcDeCodeNameById(this.view.model.appDataEntityId!)] =
      undefined;
    await this.form.load();
  }

  /**
   * 工作流启动
   *
   * @author lxm
   * @date 2022-09-29 20:09:27
   * @returns {*}  {Promise<void>}
   */
  async wfStart(): Promise<void> {
    // 先保存
    await this.save();

    const app = ibiz.hub.getApp(this.view.context.srfappid);
    const entityService = await app.deService.getService(
      this.view.model.appDataEntityId!,
    );

    // *获取工作流版本信息
    const res = await entityService.wf.getWFVersion();
    if (res.data.length === 0) {
      throw new RuntimeError('当前工作流版本不存在');
    }
    // todo 多个的情况要出一个确认框选择后走后续逻辑

    const wfInfo = res.data[0];
    const refKey = `WFSTART@${wfInfo.wfversion}`;

    // 处理视图上下文
    const newContext = Object.assign(this.view.context.clone(), {
      activeForm: wfInfo['process-form'],
    });
    // 处理视图参数
    const newParams = {
      processDefinitionKey: wfInfo.definitionkey,
    };

    // 查找工作流启动视图
    const startView = getAppViewRef(this.view.model, refKey);

    // *没有工作流启动视图的，自己启动工作流
    if (!startView) {
      await this.form.wfStart(newParams);
      await this.view.closeView();
      return;
    }

    // *有工作流启动视图的，由启动视图执行工作流启动
    const result: IModalData = await ibiz.commands.execute(
      OpenAppViewCommand.TAG,
      startView.refAppViewId,
      newContext,
      newParams,
    );

    // 启动视图正常关闭后关闭当前视图
    if (result.ok) {
      await this.view.closeView();
    }
  }

  /**
   * 工作流提交
   *
   * @author lxm
   * @date 2022-09-29 20:09:27
   * @returns {*}  {Promise<void>}
   */
  wfSubmit(): Promise<void> {
    return this.form.wfSubmit();
  }
}
